iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
AI 自動化

用 AI Agent 打造你的產品使用手冊產線系列 第 8

[Day 08] 產線實作 1:用 data-testid 精準定位元件

  • 分享至 

  • xImage
  •  

接下來這幾天,會開始逐一說明要怎麼順利地取得要放入使用手冊的截圖,今天會先從「定位元件」開始討論。

如果是用 Day 05 的流程圖來說,差不多是這個部分:

selector 策略的優劣排序

如果大家有寫過測試或是爬蟲,應該會知道「定位元件」是一個麻煩的事情。通常只能利用 CSS class name 或是 XPath 來定位 (在某些時候也可以考慮直接用 text),但是這幾個做法都不太穩定,很容易因為前端版本更新就讓定位失效了。

對於失效原因,稍微講細一點:

  • CSS class name:在許多 React 專案中會使用 CSS-in-JS 工具(例如 styled-components、Emotion)或 CSS Modules 這類方案,它們會在 class 後面帶上一段雜湊值。這個雜湊通常跟樣式內容或建置流程綁定,一旦程式碼或樣式有異動、重新 build,雜湊值就可能跟著改變,不能拿來當穩定的定位依據。
  • XPath:它記錄的是 DOM 結構的位置,因此只要結構改變 (e.g. 多加一層 <div>),它就失效了。
  • text:也就是畫面上顯示的文字,基本上只要換語言就會失效。

最理想的做法,是使用 id 這種唯一的屬性,因為它天生具備唯一性,不會像 class 那樣容易因為樣式或建置流程而變動。如果對象是自己公司的產品,這件事做起來也不難,只要請前端工程師 (或是其實就是你自己) 幫忙,在要定位的元件上加上 id 就可以了,技術上完全可行。

不過,實務上通常不會直接拿 id 來定位,而是會另外加一個 data-testid 屬性。原因在於 id 往往已經另有用途,例如綁定 CSS 樣式、給 JavaScript 操作 DOM、或是做錨點跳轉;一旦前端工程師之後因為改樣式或重構程式碼動到這些 id,測試就會跟著遭殃。data-testid 則是一個「專門為測試而生」的屬性,語意上就宣告了「這個屬性只給測試用,其他人不要動」,前端工程師在重構時也會刻意避開它,穩定性自然比直接用 id 高上不少。

命名規範

光靠 data-testid 存在還不夠,如果命名混亂一樣會讓維護變成災難。我個人比較偏好的做法是這個格式:

區域-元件功能
  • nav-tab_setting (導覽列的設定分頁)
  • overview-add-node (總覽頁的新增節點按鈕)
  • add-select-dialog (新增選擇對話框)

這樣寫的好處很明顯,只要看一眼,就可以大致猜出元件在哪個位置、有什麼用途,不需要再回去對照原始碼。需要注意的是,盡量不要用 index 這種可能會因為排序、篩選而改變的東西。

最後,將這整套規範完整地寫成一份 TESTID.md 放在 Repo 中,可以給人類參考,也可以放入 AI Agent 上下文中,讓它知道該怎麼設計。

大規模補齊

如果專案已經有一定規模,回頭補 data-testid 是一件頗麻煩的事情。不過,老話一句,反正現在有 AI Agent,問題並不大。只是在呼叫 AI Agent 補 data-testid 時,建議依照頁面處理,並準備好 TESTID.md 規範文件,接著再人工審核改動 (i.e. git diff)。

後續有頁面時,能順手補上 data-testid 是最理想的,不過,就算真的漏掉了,用先前的做法再請 AI Agent 補齊,也是可行的,問題不大。

這樣肯定可以精準定位了... 嗎?

雖然前面一直在吹捧 data-testid 這個方法有多實用,但還是難免有些需要注意的地方。

1. UI 框架的包裝元件,attribute 不一定會傳到真正的 DOM 節點

舉例來說,某些 UI 框架的 <Button> 元件,如果沒有特別設計「透傳(pass-through)未知 attribute」的機制,寫在 <Button data-testid="submit"> 上的屬性,可能根本不會出現在最終渲染出來的 <button> DOM 節點上。

遇到「selector 抓不到」的第一直覺,不該是去改 selector 的寫法,而是先打開瀏覽器的開發者工具,確認這個屬性到底有沒有出現在真正的 DOM 裡。

2. 條件渲染的元件

有些元件只在特定狀態下才會被 mount,例如:在某個 tab 在被選中之前 (i.e. 沒被選過),內容根本不存在於 DOM 裡,而不是只是被隱藏。此時不管 selector 寫得多準確都找不到,遇到這種狀況時要記得先確保前置狀態已經完成 (e.g. 每個 tab 都選過一遍)。

3. 元件存在 DOM 不代表使用者看得到

讓 UI 元件看不到的方法有很多種,常見的包含:display:nonevisibility:hiddenopacity:0,以及直接拿其他元素覆蓋在上面 (z-index)。Playwright 對這幾種情況的判定不完全一樣:

  • display:nonevisibility:hidden 會讓 Playwright 認定元件不可見而等待逾時
  • opacity:0 的元件在 Playwright 眼中通常仍視為可見
  • 被其他元素覆蓋的話,可能會讓點擊事件變成是在上層元件上觸發,導致預期的行為無法觸發

測試也可以用 data-testid

雖然我們是精準定位元件的目的是製作使用手冊,但是這套操作應用程式的做法,其實也可以用在測試上 (尤其是 E2E 測試)。一個方法可以用在兩個地方,甚至有可能測試團隊已經處理好了,可以直接用,聽起來很不錯對吧?後續其他產線實作的內容,大家也可以順便思考看看,它對測試是否也有幫助XD

今天就先到這邊了,明天會繼續介紹其他實作細節!


上一篇
[Day 07] 用 Playwright 驅動 Electron 與 Web
下一篇
[Day 09] 產線實作 2:用注入狀態精準控制畫面
系列文
用 AI Agent 打造你的產品使用手冊產線17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言